package cn.tedu.ivos.base.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    CustomUserDetailsService userDetailsService;

    // 实现AuthenticationProvider接口的authenticate方法,用户认证用户
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 从authentication中提取用户名和密码
        // getPrincipal()表示从authentication中获取主体的对象
        // getPrincipal()表示从authentication中获取凭据的对象,也就是password
        String username = authentication.getPrincipal().toString();
        String password = authentication.getCredentials().toString();
        /*
        * 从用户详情服务加载数据信息
        * 所以此处对象需要自定义用户详情类,该类需要实现UserDetails接口
        * 是SpringSecurity规定的,用来保存用户信息的类
        * */
        UserDetails userinfo = userDetailsService.loadUserByUsername(username);
        // 检查密码是否匹配,不匹配则抛出异常
        if (!userinfo.getPassword().equals(password)){
            // 错误凭据异常
            throw new BadCredentialsException("用户名或密码不正确,请重新登录");
        }
        //如果认证成功,返回新的认证令牌
        return new UsernamePasswordAuthenticationToken(userinfo,password,userinfo.getAuthorities());
    }

    // 实现AuthenticationProvider接口的supports方法,指定本提供者支持的认证类型
    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}
